/**
 **************************************************************************************************************************
 * Interface to represent geometries
 **************************************************************************************************************************
 * @file RBGeometry.h
 **************************************************************************************************************************/


#ifndef __RBGEOMETRY_H__
#define __RBGEOMETRY_H__


/**************************************************************************************************************************
 * Includes
 **************************************************************************************************************************/
#include "RBEntity.h"
#include "RBTSpatialComponent.h"

#include "RBBVolume.h"
#include "RBGeometryPrimitiveType.h"
#include "RBIndexData.h"
#include "RBVertexData.h"
#include "RBMaterial.h"

/**************************************************************************************************************************
 * Forward declarations
 **************************************************************************************************************************/
class RBVertexData;
class RBIndexData;
class RBLight;
class RBStream;
class RBTechniqueExtraData;
class RBEffectTechnique;

/**************************************************************************************************************************
 * Classes
 **************************************************************************************************************************/

RBDeclareSmartPointer(RBGeometry);

RBDeclareHandle(RBGeometry);
RBDeclareHandle(RBBVolume);

class RBGeometry :  public RBTSpatialComponent<RBGeometry>
{
public:
    RB_DECLARE_COMPONENT(RBGeometry);

    // If no transform is provided, a new transform will be created
                            RBGeometry          (RBEntityHandle entityHandle, RBTransformComponentHandle xForm = InvalidHandle);
    virtual                ~RBGeometry          ();

    // Create a triangle list based on these parameters: it's just a helper function that allocates Vertex / Index Buffers and create a good Vertex Declaration
    static RBGeometryHandle CreateGeometry      (uint32 uiVertexCount, uint32 uiIndexCount,  float3* pPositions, uint16* pIndices, RBGeometryPrimitiveType::EType ePT,
                                                 RBEffectPass* pEffectPass,
                                                 float3* pNormals = 0, float2* pTextures = 0, uint32 uiTextureSetCount = 0, float3* pColors = 0, float3* pBinormals = 0, float3* pTangents = 0,
                                                 bool bIsVBDynamic = false, bool bIsIBDynamic = false);

    static RBGeometryHandle CreateGeometry      (RBVertexBuffer* pVB, RBVertexDeclaration* pVtxDecl, RBIndexBuffer* pIB, RBGeometryPrimitiveType::EType ePT);

    RBMaterial*             GetMaterial         () const;
    RBGeometryPrimitiveType::EType GetPrimitiveType    () const;

    void                    SetMaterial         (RBMaterial* pMaterial);
    void                    SetVertexData       (RBVertexDeclaration* vertex_decl, RBVertexBuffer* vb, uint32 vertex_count, uint32 vertex_start = 0);
    void                    SetIndexData        (RBIndexBuffer* index_buffer, uint32 index_count, uint32 index_start = 0);
    void                    SetPrimitiveType    (RBGeometryPrimitiveType::EType ePrimitiveType);

    virtual void            Serialize           (RBStream& rbStream);
    void                    CopyMembers         (RBGeometryHandle handleDest);

    // Flags for rendering processs
    bool                    IsShadowCaster      : 1;
    bool                    IsReflective        : 1;
    bool                    IsVisible           : 1;

    // Used for render sorting in rendering process
    uint8                   Priority            : 5;

    // Custom flags for user's application
    uint32                  RenderFlags         : 24;

    RBEffectDataContainer   DataContainer;

    uint32                  VertexStart;
    uint32                  VertexCount;

    RBVertexDeclarationPtr  VertexDeclaration;
    RBVertexBufferPtr       VertexBuffer;

    RBIndexBufferPtr        IndexBuffer;
    uint32                  IndexStart;
    uint32                  IndexCount;


protected:
    RBMaterialPtr             m_spMaterial;
    RBGeometryPrimitiveType::EType   m_ePrimitiveType;
};

#include "RBGeometry.inl"

/**************************************************************************************************************************/

#endif // __RBGEOMETRY_H__
